package com.suxin.jvm;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.lang.ref.WeakReference;
import java.util.concurrent.TimeUnit;

/**
 * @author Tang
 * @classname ThreadLocalTest
 * @description [  ]
 * @date 2021/3/6 18:28
 */

@Data
@AllArgsConstructor
@NoArgsConstructor
class Car {
    private double price;
    private String color;
}

public class ThreadLocalTest {

    private ThreadLocal<byte[]> threadLocal = ThreadLocal.withInitial(() -> {
        return null;
    });

    byte[] bytes = new byte[1024 * 64];

    public static void main(String[] args) {

        Car car = new Car(12.4, "color...");
        WeakReference<Car> weakReference = new WeakReference<>(car);

        int i = 0;

        while (true) {
            if (weakReference.get() != null) {
                i++;
                System.out.println("Object is alive for "+i+" loops - "+weakReference);
            }else {
                System.out.println("Object has been collected.");
                break;
            }
        }
    }

    private static void mainTest() {
        try {
            TimeUnit.SECONDS.sleep(20);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        Runtime runtime = Runtime.getRuntime();

        System.out.println("开始执行....可用内存:" + runtime.totalMemory() + "空闲内存:" + runtime.freeMemory());

        test01();

        System.out.println("结束执行....可用内存:" + runtime.totalMemory() + "空闲内存:" + runtime.freeMemory());

        System.gc();

        try {
            TimeUnit.SECONDS.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private static void test02() {
        ThreadLocalTest test = new ThreadLocalTest();
        test.threadLocal.set(test.bytes);
        try {
            TimeUnit.SECONDS.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        test.threadLocal.remove();
    }

    private static void test01() {
        ThreadLocalTest test = new ThreadLocalTest();
        test.threadLocal.set(test.bytes);
        test.threadLocal = null;
        System.out.println("清除引用....");
    }

}